home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / programm.ing / m2posx10.zoo / m2posix.10 / doc / m2posix.txt next >
Encoding:
Text File  |  1993-12-21  |  18.0 KB  |  426 lines

  1. Was ist M2POSIX ?
  2. =================
  3.  
  4. Diese Modulsammlung soll einige der POSIX-Systemaufrufe (die bisher
  5. nur für ``C'' definiert sind) auch unter Modula-2 verfügbar machen.
  6. Insbesondere unter GEMDOS werden ja manche Dinge völlig
  7. unterschiedlich zu *IX-Systemen, und damit auch POSIX, gehandhabt. Ich
  8. denke da nur an das Suchen von Dateien: Unter GEMDOS werden dazu die
  9. Betriebssystemaufrufe "Fsfirst()" und "Fsnext()" benutzt, unter POSIX
  10. wird ein Verzeichnis mit "opendir()" geöffnet, jeweils der Name der
  11. nächsten im Verzeichnis enthaltenen Datei mit "readdir()" ermittelt,
  12. mit "fnmatch()" wird überprüft, ob der Name mit der oder den gesuchten
  13. übereinstimmt (dabei können die ``Wildcards'' *, ? und [...] benutzt
  14. werden) und schließlich werden mit "stat()" alle weiteren
  15. Informationen über die Datei eingeholt (unter GEMDOS stehen die
  16. vorhandenen Informationen in der DTA). Ein Beispiel für die Ermittlung
  17. von Dateien nach diesem Muster ist in LISTDIR.MPP enthalten, das ein
  18. sehr vereinfachtes ``ls'' darstellt. Außerdem können Pfadnamen nach
  19. *IX-Konvention angegeben werden (z.B. / statt \); diese werden, soweit
  20. möglich, in DOS-Äquivalente überführt. Für die Länge von Pfadnamen gibt
  21. es (bei den meisten Prozeduren) keine Begrenzung.
  22.  
  23. Als Grundlage dieser Modulsammlung diente die ``C''-Bibliothek MiNTLib
  24. von Eric R. Smith, dem Autor von MiNT. Diese Bibliothek macht die
  25. speziellen Eigenschaften von MiNT, dem GEMDOS-Multitasking-Ersatz bzw.
  26. der MultiTOS-Grundlage, auch innerhalb der (*IX)-Standardbibliothek
  27. für ``C''-Compiler, speziell dem GNU-C-Compiler, zugänglich.
  28.  
  29. Abgesehen vom reinen Übertragen ``C'' --> Modula sind einige
  30. Funktionen gleichgeblieben, aber bei den meisten habe ich erweitert,
  31. verkürzt, verändert, Fehler beseitigt, Fehler hinzugefügt oder sonst
  32. irgendwas. Ich habe auch versucht die Funktionen etwas mehr dem
  33. POSIX-Standard anzugleichen. Bei der Modulaufteilung und der
  34. Namensgebung war ich manchmal etwas ratlos, aber zumindest die
  35. Funktionsnamen sind, bis auf wenige Ausnahmen, gleichgeblieben. Wer
  36. einen Compiler hat, der Unterstriche in Bezeichnern erlaubt, und
  37. lieber die Originalnamen verwenden möchte, kann die Module mit dem
  38. Präprozessor und der Datei POSIX_ID.M2H bearbeiten, die die
  39. entsprechenden Namensumsetzungen enthält. Zeitweise war für die
  40. Moduleinteilung auch ein einzelnes Modul im Gespräch, z.B. 'SYS' oder
  41. 'POSIX', aber das wäre wohl ein ziemliches Monster an Umfang geworden;
  42. auch die Struktur der POSIX-C-Header zu übernehmen schien mir nicht so
  43. geeignet, da hier die Verteilung der Funktionen schlecht geregelt wäre
  44. (in 'UNISTD' stände dann fast alles und in den anderen Modulen, wie
  45. 'STAT', 'DIRENT' u.ä. jeweils nur ein paar wenige Funktionen).
  46. Zusammengehörende Funktionen sind zwar in den jeweiligen Modulen
  47. zusammengefaßt, es ist aber ein Modul POSIX1 vorhanden, in dem alle
  48. POSIX-Funktionen, -Typen und -Konstanten als Reexport bzw.
  49. Prozedurvariable deklariert sind, sodaß der Import aus einem einzigen
  50. Modul ausreicht, ohne daß ein Riesenmodul entsteht oder zusätzlicher
  51. Verwaltungsaufwand zur Laufzeit. Auf die gleiche Weise gibt es ein
  52. Modul ANSIC, in dem Funktionen reexportiert werden, die dem ANSI-C-
  53. Standard zuzuordnen sind und zumindest teilweise ebenfalls POSIX-1-
  54. Funktionen sind.
  55.  
  56. Die Funktionen machen, soweit möglich, von MiNT Gebrauch, falls dieses
  57. geladen ist. Es sollte aber mindestens die Version 0.96 benutzt
  58. werden, da nur überprüft wird, ob MiNT vorhanden ist, und nicht,
  59. welche Version benutzt wird -- mit Version 0.95 oder kleiner laufen
  60. einige Funktionen nicht! Dies ist eine Änderung gegenüber den vorigen
  61. Versionen von M2POSIX, aber ich gehe davon aus, daß jemand, der MiNT
  62. einsetzt, entweder MultiTOS besitzt, oder sich selbst eine lauffähige
  63. Version von MiNT aus den frei verfügbaren Quelltexten erzeugen kann,
  64. oder jemanden kennt, der dies kann.
  65.  
  66. Diese Module bestehen nicht aus reinem Modula-Quellcode, sondern
  67. enthalten noch Kommandos eines ``C''-Präprozessors, der die
  68. Übersetzbarkeit der Module unter verschiedenen Compilern erleichtern
  69. soll. Nähere Informationen zum Präprozessor geben die folgenden
  70. Abschnitte.
  71.  
  72.  
  73. Für wen ist M2POSIX geeignet ?
  74. ==============================
  75.  
  76. Diese Modulsammlung ist nichts für Anfänger! Wer sich mit den Modulen
  77. befassen will, sollte schon mit einem Kommandointerpreter umgehen
  78. können, und wissen wie ein Präprozessor zu benutzen ist. Weiterhin
  79. sollte man bereit sein, sich auf ein bißchen Experimentieren
  80. einzulassen. Wer Änderungen vornehmen will, muß vor allem aufmerksam
  81. die Implementationsmodule und die Header-Dateien durchsehen. Also
  82. nochmal: DIESE MODULE SIND NUR ETWAS FÜR LEUTE, DIE BEREIT SIND, SICH
  83. MEHR ODER WENIGER INTENSIV DAMIT AUSEINANDERZUSETZEN!!!
  84.  
  85. An zusätzlichen Programmen, neben einem M2-Compiler, werden benötigt:
  86.  
  87. o Ein Kommandointerpreter, vorzugsweise GULÄM.PRG.
  88.  
  89. o Ein ``C''-Präprozessor, vorzugsweise GCC-CPP.TTP bzw. CPP.TTP
  90.   (Der GNU-C-Präprozessor wird im Verzeichnis 'cpp' mitgeliefert).
  91.  
  92. Diese Programme findet man bestimmt auf jedem FTP-Server (z.B.
  93. ftp.uni-muenster.de, ftp.uni-paderborn.de, ftp.cs.tu-berlin.de). Der
  94. Präprozessor dürfte meistens zusammen mit dem GNU-C-Compiler in einem
  95. gemeinsamen Archiv zu finden sein. Außerdem gibt es beide Programme
  96. auch noch auf (teuren) PD-Disketten.
  97.  
  98.  
  99.  
  100. Bedingungen, unter denen M2POSIX verwendet werden darf
  101. ======================================================
  102.  
  103. Die Verwendung von M2POSIX unterliegt keiner Einschränkung, außer daß
  104. bei der Weitergabe alle Dateien unverändert enthalten sein müssen
  105. (abgesehen von einer Komprimierung). Natürlich dürfen für die
  106. Weitergabe auch keine Gebühren zusätzlich zu Diskettenkosten,
  107. Kopierkosten o.ä. verlangt werden!
  108.  
  109. Ich übernehme keinerlei Verantwortung für die Korrektheit und
  110. Verwendbarkeit der Funktionen. Wer M2POSIX benutzt, ist selber für
  111. alle evtl. Folgen verantwortlich.
  112.  
  113.  
  114. Warum ein Präprozessor ?
  115. ========================
  116.  
  117. Leider verstehen nicht alle Modula-Compiler einen gemeinsamen
  118. ``Dialekt''. Sicher -- die Sprache ist in einer Sprachbeschreibung
  119. definiert worden, aber zum einen gibt es mehrere Versionen dieser
  120. Beschreibung (PIM1..PIM4), zum anderen ist lediglich die Syntax formal
  121. definiert (BNF), die Semantik aber in Form natürlichsprachlicher
  122. Texte, sodaß einige Dinge nicht eindeutig festgelegt sind (werden
  123. können). Außerdem haben die Compiler-Hersteller auch eigene
  124. Restriktionen und/oder Erweiterungen hinzugefügt. Diese Situation wird
  125. sich erst ändern, wenn sich die Hersteller an die ISO-Norm für
  126. Modula-2 halten, hier wird nämlich auch die Semantik bis ins kleinste
  127. formal definiert.
  128.  
  129. Die Unterschiede bestehen vor allem in folgenden Bereichen:
  130.  
  131. o standardmäßige Größen von INTEGER und CARDINAL (16 oder 32 Bit)
  132.  
  133.  
  134. o Typtransfer: das Ändern des Typs eines Ausdrucks, ohne daß dafür
  135.   Code generiert wird; d.h. das betreffende Bitmuster wird nur anders
  136.   interpretiert, bzw. die Typprüfung des Compilers umdirigiert.
  137.  
  138. o Typkonvertierung: das Ändern des Typs eines Ausdrucks, wobei evtl.
  139.   Code generiert wird, z.B. bei der Wandlung zwischen SHORT- und
  140.   LONG-Typen.
  141.  
  142. o Adressarithmetik
  143.  
  144.  
  145. o Setzen und Lesen von Prozessorregistern.
  146.  
  147. o Kennzeichnung von LONG-Konstanten
  148.  
  149.  
  150. Um diese Unterschiede möglichst aus dem Weg zu räumen, werden die
  151. Module mit Präprozessormakros versehen, die z.T. von der Syntax her
  152. wie ISO-M2-Code aussehen (z.B. CAST, VAL, ADDADR, SUBADR, DIFADR, INT
  153. usw.). In der Datei PORTAB.M2H, die die Definitionen enthält, werden
  154. die Makros dann auf die compilerspezifischen Konstruktionen
  155. abgebildet. Eine weitere Datei mit Makros ist OSCALLS.M2H; sie enthält
  156. die Definitionen für die Aufrufe der Betriebssystemfunktionen.
  157.  
  158. Durch das Konzept der Makros können die Module also einheitlich für
  159. unterschiedliche Compiler programmiert werden; die Unterschiede werden
  160. dann erst beim Bearbeiten mit dem Präprozessor berücksichtigt, das am
  161. besten als erster Pass des Übersetzungsvorganges betrachtet wird. (Bei
  162. ``C''-Compilern ist dieses Vorgehen ja bereits integriert, es hindert
  163. einen aber niemand daran, dies auch für andere Sprachen, wie Modula-2,
  164. zu benutzen.)
  165.  
  166. Um Module mit und ohne Makros leicht auseinanderhalten zu können,
  167. verwende ich folgende Extensionen für M2-Dateien mit
  168. Präprozessorkommandos:
  169.  
  170.     .DPP    für Definitionsmodule,
  171.     .IPP    für Implementationsmodule und
  172.     .MPP    für Programmodule
  173.  
  174. Diese Kennzeichnung ist natürlich nur ein Vorschlag.
  175.  
  176.  
  177. Die Benutzung eines ``C''-Präprozessors hat natürlich(?) auch
  178. Nachteile:
  179.  
  180. o Die Modula-Kommentarklammern sind keine ``C''-Kommentarklammern --
  181.   deshalb werden Zeichenketten, die mit definierten Makros
  182.   übereinstimmen, auch innerhalb von Modula-Kommentaren durch den
  183.   Präprozessor ersetzt. Als Behelf kann man die entsprechenden
  184.   Schlüsselworte innerhalb der Modula-Kommentare in doppelte
  185.   Anführungszeichen (") setzen, da der Präprozessor, zumindest der
  186.   GNU-C-Präprozessor, keine Makros in C-Strings ersetzt.
  187.  
  188. o Der Backslash '\' hat für den Präprozessor eine Spezialbedeutung; je
  189.   nach dem (oder den) nachfolgenden Zeichen wird für die Kombination
  190.   der Zeichen nachher durch den Compiler ein Spezial (meistens
  191.   Control)-Zeichen eingesetzt. Obwohl nicht der Präprozessor für die
  192.   Ersetzung verantwortlich ist, meldet er jedoch einen Fehler (->
  193.   "unterminated string constant"), wenn hinter dem Backslash in einer
  194.   Zeichen- oder Stringkonstante kein Zeichen mehr folgt. (Das gilt
  195.   zumindest für den GNU-C-Präprozessor.)
  196.  
  197.  
  198.  
  199. Präprozessieren der Module
  200. ==========================
  201.  
  202. Im folgenden wird davon ausgegangen, daß ``Guläm'' als CLI zusammen
  203. mit den vorgefertigten Batch-Dateien benutzt, und als Präprozessor der
  204. GNU-C-Präprozessor verwendet wird. Wer einen anderen CLI (z.B. Mupfel)
  205. benutzt, oder gar einen anderen Präprozessor, muß entsprechende
  206. Änderungen vornehmen.
  207.  
  208. Der Aufbau der Batch-Dateien ist als Kommentar in den Dateien selbst
  209. enthalten, es sollte also keine größeren Schwierigkeiten geben, diese
  210. an andere Gegebenheiten anzupassen.
  211.  
  212. Beim Präprozessieren wird am besten folgende Reihenfolge eingehalten:
  213.  
  214. 1) Erstellen einer Datei X<System>.G, die die Batch-Datei X_M2.G mit
  215.    den nötigen Parametern aufruft, d.h. Name des Compilers,
  216.    Zielverzeichnis, Endungen von Definitions- und
  217.    Implementationsmodulen. Meine Datei für LPR-Modula sieht so aus:
  218.  
  219.       Name: XLPR.G
  220.     Inhalt: x_m2 LPRM2 m: def mod
  221.  
  222.    Die präprozessierten Module landen bei mir auf der RAM-Disk M:\.
  223.  
  224.    Eine ähnliche Datei muß auch für das Präprozessieren der Testmodule
  225.    erstellt werden, wobei hier nur die Endung für Programmodule
  226.    benötigt wird:
  227.  
  228.       Name: TLPR.G
  229.     Inhalt: t_m2 LPRM2 m: mod
  230.  
  231. 2) In der Datei PORTAB.M2H werden gleich zu Anfang die Makros
  232.  
  233.     #if 0
  234.     #define __RES_ON_STACK__
  235.     #endif
  236.  
  237.     #if 1
  238.     #define __LONG_WHOLE__
  239.     #endif
  240.  
  241.     #if 1
  242.     #define __LONG_REAL__
  243.     #endif
  244.  
  245.     #if 1
  246.     #define __REG_VARS__
  247.     #endif
  248.  
  249.    definiert. Die Einstellung dieser Makros kann auf Wunsch verändert
  250.    werden. Falls die Bedingung im umgebenden #if gleich 0 ist, ist das
  251.    Makro undefiniert und damit ausgeschaltet, sonst ist es eingeschaltet.
  252.    Falls die entsprechende Option bei einem Compiler nicht einstellbar
  253.    ist, hat das Makro keine Bedeutung. Falls die Option nur beim Start
  254.    des Compilers aber nicht im Quelltext einstellbar ist, MUß(!) dieses
  255.    Makro mit der globalen Compilereinstellung übereinstimmen. Falls die
  256.    Option dagegen im Quelltext gesetzt werden kann, wird sie automatisch,
  257.    zusammen mit anderen Grundeinstellungen, abhängig von diesem Makro
  258.    gesetzt.
  259.    Die Bedeutung der Makros ist wie folgt:
  260.  
  261.    __RES_ON_STACK__:
  262.    Die Ergebnisse von Funktionen werden auf dem Stack übergeben, sonst
  263.    in Registern (D0/D1).
  264.  
  265.    __LONG_WHOLE__:
  266.    Die Typen CARDINAL und INTEGER sind identisch mit LONGCARD und
  267.    LONGINT, also den größten Ganzzahltypen, entsprechend ISO, sonst
  268.    mit SHORTCARD und SHORTINT.
  269.  
  270.    __LONG_REAL__:
  271.    Der Typ REAL ist identisch mit LONGREAL, sonst mit SHORTREAL.
  272.  
  273.    __REG_VARS__:
  274.    Lokale Variablen, die mit dem Attribut __REG__ versehen sind, werden
  275.    als Registervariablen deklariert, sonst nicht.
  276.  
  277. 3) Eintragen des vollständigen Pfades der Datei PORTAB.M2H in die
  278.    Batch-Datei M2PPX.G. PORTAB.M2H kann in einem beliebigen
  279.    Verzeichnis stehen, da nur an dieser einen Stelle auf sie
  280.    zugegriffen wird. Sinnvoll ist es jedoch, sie in dem Verzeichnis
  281.    unterzubringen, wo auch die anderen Header-Dateien stehen, falls
  282.    solche existieren (z.B. vom ``C''-Compiler).
  283.  
  284. 4) Die Batch-Dateien (bei mir M2PPX.G, X_M2.G, XLPR.G, T_M2.G und
  285.    TLPR.G), der Präprozessor CPP.TTP bzw. GCC-CPP.TTP und das kleine
  286.    Programm X2D1.TOS werden in ein Verzeichnis kopiert, wo der
  287.    Kommandointerpreter sie als ausführbare Dateien finden kann; das
  288.    Verzeichnis muß also in der Environmentvariablen PATH erwähnt sein.
  289.    Bei mir steht deshalb in GULAM.G folgende Definition (die ab-
  290.    schließenden Punkte sollen weitere Pfade andeuten):
  291.  
  292.     set path '.,e:\usr\bin,e:\bin,...' ,
  293.  
  294.    wobei die Batch-Dateien und X2D1.TOS im ersten Verzeichnis stehen
  295.    und der Präprozessor im zweiten. Bemerkung: Nach einem 'set path'
  296.    wird bei Guläm automatisch die Environmentvariable PATH gesetzt.
  297.  
  298. 5) Alle Dateien mit den Endungen .DPP, .IPP und .MPP und die Datei
  299.    OSCALLS.M2H in ein Verzeichnis kopieren. OSCALLS.M2H kann
  300.    alternativ ebenfalls in das Verzeichnis kopiert werden, wo die
  301.    anderen Header-Dateien stehen, dann muß jedoch der Präprozessor
  302.    wissen, wo er zu suchen hat; in meinem GULAM.G steht deswegen
  303.    folgende Zeile:
  304.  
  305.     setenv GNUINC e:\usr\include\m2,e:\usr\include
  306.  
  307.    Im ersten Verzeichnis stehen dabei alle Modula-2-Header, im zweiten
  308.    die ``C''-Header.
  309.  
  310. 6) Guläm starten und in das Verzeichnis mit den M2-Dateien wechseln.
  311.  
  312. 7) Einfach die in Punkt 1) erstellten Batch-Dateien aufrufen, z.B.
  313.    mit:
  314.  
  315.     XLPR
  316.  
  317.    und wenn kein Fehler aufgetreten ist:
  318.  
  319.     TLPR
  320.  
  321.    Dann sollten im Zielverzeichnis die Module in reinem M2-Quellcode
  322.    stehen. Die Module können dann mit dem Modula-Compiler übersetzt
  323.    werden. Da die Module teilweise voneinander abhängig sind, muß beim
  324.    Übersetzen natürlich eine bestimmte Reihenfolge eingehalten werden,
  325.    hierfür kann aber einfach die gleiche Reihenfolge benutzt werden,
  326.    wie sie in der Batch-Datei X_M2.G für das Präprozessieren verwendet
  327.    wurde.
  328.  
  329.  
  330. Anpassung an andere Compiler
  331. ============================
  332.  
  333. Gleich vorneweg: Folgende Compiler werden nicht berücksichtigt:
  334.  
  335. o ana-systems m2 (ANAM2): ein Shareware-Compiler, der sich an PIM2
  336.   orientiert; der Hauptnachteil ist aber, daß er keine arithmetischen
  337.   16-Bit-Typen kennt.
  338.  
  339. o Modular Systems (MSM2): orientiert sich auch irgendwo zwischen PIM2
  340.   und PIM3, hat aber viel zu viele Eigenheiten.
  341.  
  342. o FTL-Modula: hat einige Compilerfehler, die einem das Leben schwer,
  343.   wenn nicht gar unmöglich machen, zumindest in der Version 1.18.
  344.  
  345. Ich behaupte nicht, daß diese Compiler schlecht wären, es ist mir aber
  346. zu viel Arbeit, auf die Eigenheiten dieser Systeme Rücksicht zu
  347. nehmen.
  348.  
  349. Momentan werden nur die Compiler LPR (PD-Compiler der TU-München),
  350. Megamax, Hänisch und TDI (kommerzielle Compiler) unterstützt; da der
  351. SPC-Compiler (nur der Compiler, nicht etwa das ganze System) aber fast
  352. identisch zu LPR ist, dürfte auch dieser geeignet sein (Ähnliches
  353. dürfte auch für andere Compiler gelten, die vom Original-ETH-Compiler
  354. abstammen). Wer die Module an sein System anpassen will, muß auf jeden
  355. Fall die Header-Datei PORTAB.M2H anpassen, wahrscheinlich auch
  356. OSCALLS.M2H, da dort die Betriebssystemaufrufe definiert werden.
  357. Außerdem muß im Modul 'cmdline' die systemspezifische Prozedur zur
  358. Ermittlung der 'Basepage' verwendet werden, vielleicht ist die
  359. 'Basepage' auch als Variable in irgendeinem Systemmodul deklariert. Im
  360. Modul 'lib' sind einige Assemblerprozeduren; die Routinen selber sind
  361. allgemein gehalten, sodaß hier keine Anpassung nötig sein dürfte,
  362. evtl. müssen aber andere Register gerettet werden, dazu steht aber ein
  363. Kommentar im Quelltext.
  364.  
  365. Es kann auch sein, daß im Quellcode spezielle Abfragen auf das System
  366. nötig werden, z.B in der Form:
  367.  
  368.     ...
  369.     #if (defined <System>M2)
  370.         ...
  371.     #else
  372.         ...
  373.     #endif
  374.     ...
  375.  
  376. Es sollte jedoch versucht werden, sämtliche Compiler-Abhängigkeiten in
  377. die Header-Dateien zu verlegen -- soweit möglich.
  378.  
  379. Am besten ist es, mal die Testmodule (mit der Endung .MPP) zu
  380. übersetzen, und sowohl unter GEMDOS als auch unter MiNT laufen zu
  381. lassen -- vorausgesetzt natürlich, daß der Compiler dazu überredet
  382. werden kann, die Module zu übersetzen. Falls der Compiler für INTEGER
  383. und CARDINAL per Option 16 oder 32 Bit benutzen kann, sollten auch
  384. beide Einstellungen ausprobiert werden.
  385.  
  386. Beim HM-Compiler werden nur noch Versionen >= 5.1 unterstützt.
  387.  
  388. Beim LPR-Compiler müssen alle Tests in der Shell ausgeschaltet
  389. werden, da es Assemblerprozeduren mit Rückgabewert gibt (Das Laufzeit-
  390. system beschwert sich sonst über ein fehlendes RETURN.)
  391.  
  392. Die ``Test''-Module sind allerdings keine vollständigen Tests,
  393. vielmehr werden einfach nur einige der Funktionen mit
  394. unterschiedlichen Parametern aufgerufen, und geprüft, ob das Erwartete
  395. passiert. Z.T. ist auch die Überprüfung durch den Benutzer
  396. erforderlich, oder es werden einfach nur Systemeinstellungen
  397. abgefragt. Für weitere Informationen über die Anwendung der Testmodule
  398. sollte der Quellcode durchgesehen werden.
  399.  
  400. Zu Demonstrationszwecken wurden einige der Testmodule auch übersetzt.
  401.  
  402. Da bei solchen Anpassungen einiges schief gehen kann, sollte
  403. vielleicht eine RAM-Disk benutzt werden, auf der dann Dateien ohne
  404. Auswirkungen zerstört werden können... Auf jeden Fall übernehme ich
  405. keine Verantwortung für zerschossene Festplatten oder ähnliches...
  406.  
  407. Eine Anpassung an MSDOS- oder gar *IX-Systeme benötigt sicherlich
  408. einiges an Arbeit, ich will aber niemanden davon abhalten...
  409.  
  410. Generell: Ich würde mich freuen, wenn mir jemand, der eine Anpassung
  411. vorgenommen hat, eine Kopie zukommen läßt. Das gilt natürlich auch für
  412. Anregungen, Fehlermeldungen u. ä.
  413.  
  414. Meine Adresse lautet:
  415.  
  416. Holger Kleinschmidt
  417. Promenadenstr. 11 B
  418. 12207 Berlin
  419.  
  420.  
  421. Literatur
  422. =========
  423.  
  424. Zlotnick, F.. The POSIX.1 Standard: A Programmer's Guide. The
  425. Benjamin/Cummings Publishing Company, 1991
  426.